package com.gao.activitidemo.activititest;

import com.gao.activitidemo.pojo.Evection;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.util.*;

/**
 * 流程启动时设置变量
 * @author gaofeng
 * @date 2022年09月14日 19:50
 */
public class GlobalVarTest {

    /**
     * 流程部署
     */
    @Test
    public void testActivitiDeployment() {
        // 1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2. 获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 3.进行流程部署, 定义一个流程名称, 把bpmn和png部署到数据库中
        Deployment deploy = repositoryService.createDeployment().name("出差申请流程")
                .addClasspathResource("bpmn/evection-global.bpmn20.xml")
                .addClasspathResource("bpmn/evection-global.png")
                .deploy();
        // 4.输出部署信息
        System.out.println("流程部署id:" + deploy.getId());
        System.out.println("流程部署id:" + deploy.getName());
    }

    /**
     * 启动流程实例 设置流程变量
     * 操作的数据表:
     * act_hi_actinst          流程实例执行历史
     * act_hi_identitylink     流程的参与用户信息历史
     * act_hi_procinst         流程实例历史信息
     * act_hi_taskinst         流程任务历史信息
     * act_ru_execution        流程正在执行信息
     * act_ru_identitylink     流程的参与用户信息
     * act_ru_task             任务信息
     */
    @Test
    public void testStartProcess() {
        // 1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.获取RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Map<String, Object> map = new Hashtable<>() ;
        Evection build = Evection.builder().days(2d).startTime(new Date("2022-09-14")).endTime(new Date("2022-09-16")).build();
        map.put("evection", build) ;
        // 设置负责人
        // 3.根据流程定义的id启动
        ProcessInstance evection = runtimeService.startProcessInstanceByKey("evection-global", map);
        // 4.输出
        System.out.println("流程定义的id: " + evection.getProcessDefinitionId());
        System.out.println("当前活动的id: " + evection.getActivityId());
    }

    /**
     * 完成个人任务
     */
    @Test
    public void testCompletePersonalTask() {
        // 1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.创建TaskService
        TaskService taskService = processEngine.getTaskService();
        // 3.根据任务id完成任务
        // 根据流程key和负责人查任务,根据taskId完成任务
        Task task = taskService.createTaskQuery().processDefinitionKey("evection-global").taskCandidateOrAssigned("李四").singleResult();
        if (Objects.nonNull(task)) {
            taskService.complete(task.getId());
            // 第二种,完成任务的时候设置流程变量
//            taskService.complete(task.getId(), new HashMap<>());
        }
    }

    /**
     * 第三种:通过当前流程实例设置
     */
    @Test
    public void setGlobalVariablesByExecutionId() {
        // 当前流程实例id  必须当前未结束,
        String executionId = "1" ;
        // 1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.创建RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        // 3.设置
        Evection evection = Evection.builder().days(3D).build();
        // 一次只能设置一个
        runtimeService.setVariable(executionId, "evection", evection);
        // 一次设置多个值
//        runtimeService.setVariables(executionId, new HashMap<>());
    }

    /**
     * 第四种:通过当前任务设置
     */
    @Test
    public void setGlobalVariablesByTaskId() {
        // 当前任务id  必须是当前待办任务id,act_ru_task中存在; 如果该任务结束,则报错
        String taskId = "9527" ;
        // 1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.创建RuntimeService
        TaskService taskService = processEngine.getTaskService();
        // 3.设置
        Evection evection = Evection.builder().days(3D).build();
        // 一次只能设置一个
        taskService.setVariable(taskId, "evection", evection);
        // 一次设置多个值
//        taskService.setVariables(executionId, new HashMap<>());
    }

    /**
     * 第四种:通过当前任务设置局部流程变量
     *  只能在当前任务结束前使用
     */
    @Test
    public void setLocalVariablesByTaskId() {
        // 当前任务id  必须是当前待办任务id,act_ru_task中存在; 如果该任务结束,则报错
        String taskId = "9527" ;
        // 1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.创建RuntimeService
        TaskService taskService = processEngine.getTaskService();
        // 3.设置
        Evection evection = Evection.builder().days(3D).build();
        // 一次只能设置一个
        taskService.setVariableLocal(taskId, "evection", evection);
        // 一次设置多个值
//        taskService.setVariableLocal(executionId, new HashMap<>());
    }

    /**
     * 通过流程办理时设置局部流程变量
     */
    @Test
    public void setLocalVariablesByTaskId2() {
        // 1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.创建TaskService
        TaskService taskService = processEngine.getTaskService();
        // 3.根据任务id完成任务
        Map<String, Object> map = new HashMap<>();
        // 根据流程key和负责人查任务,根据taskId完成任务
        Task task = taskService.createTaskQuery().processDefinitionKey("evection-global").taskCandidateOrAssigned("李四").singleResult();
        if (Objects.nonNull(task)) {
            taskService.setVariablesLocal(task.getId(), map);
            taskService.complete(task.getId());
            // 第二种,完成任务的时候设置流程变量
//            taskService.complete(task.getId(), new HashMap<>());
        }
    }
}
